<?php

class templateEngine {
    
    public $mainTemplate;
    public $openTemplateInWindow = false;
    private $templateContent = array();
    private $templateExtensions = array('.htm','.html','.tpl');
    private $javascriptsFiles = array();
    private $cssFiles = array();
    
    public function __construct($mainTemplate = 'main') {
        $this->getMainTemplate($mainTemplate);
    }
    
    /*
     * @author Frank Roffel
     * @version 1.0 
     * @description Get the main template for later use. 
     * 
     */
    public function getMainTemplate($mainTemplate) {
        foreach($this->templateExtensions as $extension) {
            
            $templateFound = false;
            
            if(file_exists($GLOBALS['templatePath']. $mainTemplate . $extension)) {
                $template = file_get_contents($GLOBALS['templatePath'] . $mainTemplate . $extension);
                $this->mainTemplate = $template;
                $templateFound = true;
            }
            
            if($templateFound == false) {
                if(file_exists($GLOBALS['libaryPath'] . $GLOBALS['templatePath']. $mainTemplate . $extension)){
                    $template = file_get_contents($GLOBALS['libaryPath'] . $GLOBALS['templatePath'] . $mainTemplate . $extension);
                    $this->mainTemplate = $template;
                } 
            }
            
        }
    }
    
    public function append($html, $tag, $unique){
        $this->addHtml($html, $tag, 'append', $unique);
    }
    
    public function prepend($html, $tag, $unique){
        $this->addHtml($html, $tag, 'prepend', $unique);
    }
    
    public function assign($html, $tag, $unique){
        $this->addHtml($html, $tag, 'assign', $unique);
    }
    
    public function appendTemplate($file, $tag = 'mainContent', $unique, $checkLibaryDirectly = false){
        $this->addTemplate($file, $tag, 'append', $unique, $checkLibaryDirectly);
    }
    
    public function prependTemplate($file, $tag = 'mainContent', $unique, $checkLibaryDirectly = false) {
        $this->addTemplate($file, $tag, 'prepend', $unique, $checkLibaryDirectly);
    }
    
    public function assignTemplate($file, $tag = 'mainContent', $unique, $checkLibaryDirectly = false) {
        $this->addTemplate($file, $tag, 'assign', $unique, $checkLibaryDirectly);
    }
    
    private function addHtml($html, $tag, $mode, $unique = false){
        
        $existingContent = '';
        
        if($unique) {
            $tag = $this->makeTagUnique($tag);
        }
        
        switch($mode){
            case 'assign':
                
                $this->templateContent[$tag] = $html; 
                
                break;
            
            case 'prepend':
                
                # Check if there already is some content
                if(isset($this->templateContent[$tag])) {
                    $existingContent = $this->templateContent[$tag];
                }
                
                $this->templateContent[$tag] = $html . $existingContent;
                
                break;
            case 'append':
                # Check if there already is some content
                if(isset($this->templateContent[$tag])) {
                    $existingContent = $this->templateContent[$tag];
                }
                
                $this->templateContent[$tag] = $existingContent . $html;
                
                break;
        }
        
    }
    
    /*
     * @author Frank Roffel
     * @version 1.0 
     * @description Add a template by assigning, adding or prepending. 
     * 
     */
    private function addTemplate($file, $tag, $mode, $unique = false, $checkLibaryDirectly = false){
        
        $templateFound = false;
        $existingContent = '';
        
        # Try to find the template with one of the possible exentions
        foreach($this->templateExtensions as $extension) {
               
            if($templateFound == false) {
                
                # If we specified to check the libary folder directly, don't check the application folder
                if($checkLibaryDirectly == false) {
                    if(file_exists($GLOBALS['templatePath'].$file.$extension)) {
                        $template = file_get_contents($GLOBALS['templatePath'] . $file . $extension);
                        $templateFound = true;
                    }
                }
                
                # Check the libary folder if the template exitst
                if($templateFound == false) {
                    if(file_exists($GLOBALS['libaryPath'].$GLOBALS['templatePath'].$file.$extension)) {
                        $template = file_get_contents($GLOBALS['libaryPath'].$GLOBALS['templatePath'] . $file . $extension);
                        $templateFound = true;
                    }
                }
                
            }
            
        }
        
        # Check if we need to make the content of the template unique
        if($unique) {
            $template = $this->makeTemplateTagsUnique($template);
        }
        
        # We only add the template if it was found
        if($templateFound == true) {
            
            switch($mode) {
                case 'assign':
                    
                    $this->templateContent[$tag] = $template;
                    
                    break;
                case 'prepend':

                    # Check if there already is some content
                    if(isset($this->templateContent[$tag])) {
                        $existingContent = $this->templateContent[$tag];
                    }
                    
                    $this->templateContent[$tag] = $template . $existingContent;
                        
                    break;
                case 'append':
                    
                    # Check if there already is some content
                    if(isset($this->templateContent[$tag])) {
                        $existingContent = $this->templateContent[$tag];
                    }

                    $this->templateContent[$tag] = $existingContent . $template;
                    
                    break;
            }
            
        }
            
    }
    
    /*
     * @author Frank Roffel
     * @version 1.0 
     * @description This makes sure all the tags inside a template are unique
     * 
     */
    private function makeTemplateTagsUnique($template) {
        
        if(!isset($_SESSION['uniqueTag'])) {
            $_SESSION['uniqueTag'] = 0;
        }
        
        $_SESSION['uniqueTag']++;
        
        # Find and replace unused tags
        preg_match_all('/<--[a-zA-Z0-9]{0,100}-->/im',$template,$matches);
        
        foreach($matches[0] as $tag) {
            $oldTag = explode('--',$tag);
            $newTag = '<--'.$oldTag[1].$_SESSION['uniqueTag'].'-->';
            $template = preg_replace('<'.$tag.'>', $newTag, $template);
        }
        
        return $template;
        
    }
    
    /*
     * @author Frank Roffel
     * @version 1.0 
     * @description Make the tag we are using unique according to the ones used in the function makeTemplateTagsUnique()
     * 
     */
    private function makeTagUnique($tag) {
        
        if(isset($_SESSION['uniqueTag'])) {
            $tag = $tag . $_SESSION['uniqueTag'];
        }
        
        return $tag;
        
    }
    
    
    /*
     * @author Frank Roffel
     * @version 1.0 
     * @description Add a javascript file to the main template
     * 
     */
    public function addJavascriptFile($file, $checkLibaryDirectly = false) {
        
        $fileFound = false;
        
        # If we specified to check the libary directly, don't check the application folder
        if($checkLibaryDirectly == false) {
            
            # Check the applicationfolder if the file exists here 
            if(file_exists($GLOBALS['javascriptPath'].$file.'.js')){
                $this->javascriptsFiles[] = $GLOBALS['javascriptPath'].$file.'.js';
                $fileFound = true;
            }
            
        }
        
        # If the file is already found we don't need to check the libary
        if($fileFound == false) {
            
            # Check the libaryfolder if the file exists here
            if(file_exists($GLOBALS['libaryPath'].$GLOBALS['javascriptPath'].$file.'.js')){
                $this->javascriptsFiles[] = $GLOBALS['libaryPath'].$GLOBALS['javascriptPath'].$file.'.js';
            }
            
        }
        
    }
    
    
    /*
     * @author Frank Roffel
     * @version 1.0 
     * @description Add a css file to the main template
     * 
     */
    public function addCssFile($file, $checkLibaryDirectly = false){
        
        $fileFound = false;
        
        # If we specified to check the libary directly, don't check the application folder
        if($checkLibaryDirectly == false) {
          
            # Check the applicationfolder if the file exists here 
            if(file_exists($GLOBALS['cssPath'].$file.'.css')){
                $this->cssFiles[] = $GLOBALS['cssPath'].$file.'.css';
                $fileFound = true;
                
            }
            
        }
        
        # If the file is already found we don't need to check the libary
        if($fileFound == false) {
            
            # Check the libaryfolder if the file exists here
            if(file_exists($GLOBALS['libaryPath'].$GLOBALS['cssPath'].$file.'.css')){
                $this->cssFiles[] = $GLOBALS['libaryPath'].$GLOBALS['cssPath'].$file.'.css';
            }
            
        }
        
    }
    
    public function openTemplateInWindow($openTemplateInWindow, $width = 400, $height = 250) {
        $this->openTemplateInWindow = $openTemplateInWindow;
    }
    
    
    /*
     * @author Frank Roffel
     * @version 1.0 
     * @description Make sure there are no tags left in the template
     * 
     */
    private function cleanupTemplate($html) {
        
        # Find and replace unused tags
        $html = preg_replace('/<--[a-zA-Z0-9]{0,100}-->/im','',$html);
        
        return $html;
        
    }
    
    /*
     * @author Frank Roffel
     * @version 1.0 
     * @description Build the main template using all available templates, javascripts and cssitems we have
     * 
     */
    public function generateTemplate($toString = false) {
        
        foreach($this->javascriptsFiles as $file) {
            $this->mainTemplate = str_replace("<--javaHead-->","<script src='".$file."'></script> \n<--javaHead-->",$this->mainTemplate);
        }
        
        foreach($this->cssFiles as $file) {
            $this->mainTemplate = str_replace("<--cssHead-->","<link rel='stylesheet' type='text/css' href='".$file."' /> \n <--cssHead-->",$this->mainTemplate);
        }
        
        # Replace all tags with the content
        foreach($this->templateContent as $tag => $template) {
            $this->mainTemplate = str_replace("<--".$tag."-->",$template,$this->mainTemplate);
        }
        
        # Make sure we delete all unused tags that still remain
        $this->mainTemplate = $this->cleanupTemplate($this->mainTemplate);
        
        if($toString) {
            return $this->mainTemplate;
        } else {
            echo $this->mainTemplate;
        }
        
    }
    
}

?>
